When developing an XPages Custom Control you may encounter the issue:
Error while executing JavaScript action expression
'compositeData' not found
If your custom control contains only a single control that is one of these tags:
xp:viewColumn (View Column),
xp:column (Column),
xp:eventHandler (Event Handler),
xp:selectItem (Select Item),
xp:selectItems(Select Items)
then the compositeData is not available in "Compute Dynamically" bindings,
only in "Compute on Page Load" bindings.
Normally when a custom control is inserted into an XPage, it leaves a panel-like control
in the control tree, the UIIncludeComposite. That panel provides functionality:
- it publishes the compositeData to be available in compute dynamically bindings
- it publishes any data sources that were defined on the root of the custom control page,
and handles the other data-related properties (readonly, acl etc)
- it provides a clientId naming scope.
So if you have a custom control containing
and an outer page containing:
<xp:myCustom>
<xp:myCustom>
it ensures the 2 divs have different ids in the HTML source:
<div id="view:_id1:_id2:div1"></div>
<div id="view:_id1:_id3:div1"></div>
(the first custom control panel is _id2, and the 2nd custom control panel is _id3)
- etc. It provides all of the non-load-time custom control behavior.
The controls listed above depend on their parent container tag,
and do not work a panel is inserted in the tree between that control and their parent.
For example, for xp:column if you have
<xp:dataTable>
<xp:panel>
<xp:column>
</xp:panel>
<xp:dataTable>
then the dataTable does not find the column in its direct children,
so the column would not be output as part of the dataTable.
Hence when you create a custom control that only contains one of the tags above,
the panel will be automatically removed after the contents are loaded,
so the compositeData will not be available during dynamic bindings.
If you do want the panel to be removed, then the workaround to the "compositeData not found"
error is to use a load-time binding (in the JavaScript editor, choose "Compute on Page Load").
If you do not want the panel to be removed, you can either
add some content to the custom control page (like a <xp:br/> or a <xp:text value=" "/>),
or you can programmatically prevent the autoRemove, by adding this code to the custom control:
<xp:this.beforePageLoad><![CDATA[#{javascript:
this.setAutoRemove(false);
}]]></xp:this.beforePageLoad>